/*
*********************************************************************************************************
*                                DSP Driver for MCU
*
*                   (c) Copyright 2025 - 2025; Fortemedia Inc.; Nanjing, China
*
*                   All rights reserved.  Protected by international copyright laws.
*                   Knowledge of the source code may not be used to write a similar
*                   product.  This file may only be used in accordance with a license
*                   and should not be redistributed in any way.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* Filename      : drv_dsp.c
* Version       : V1.0.0
* Programmer(s) : ShiWei Han
*********************************************************************************************************
* Note(s)       :
*********************************************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
//#include "main.h"
//#include "memorymap.h"
//#include "spi.h"
//#include "usart.h"
//#include "gpio.h"
#include "common_def.h"

#include "drv_dsp.h"
#include "dram0.h"
#include "iram0.h"

#ifdef SUPPORT_FM1505_DMS
static const uint8_t sw_reset_dsp = 0x07;
static const uint8_t hold_dsp = 0x05;
static const uint8_t run_dsp = 0x04;
static uint8_t data_send1[BLOCK_SEND_SIZE];
static uint8_t data_recv1[BLOCK_SEND_SIZE];
static st_dsp_addr dsp_addr;
extern const reg_config_t register_config_SYS[];
extern const size_t register_config_size_SYS;
extern const reg_config_t dsp_mode1_path_SYS[];
extern const size_t dsp_mode1_path_SYS_size;
extern const reg_config_t dsp_mode1_path_AFE[];
extern const size_t dsp_mode1_path_AFE_size;
extern const reg_config_t dsp_mode1_ven_TX[];
extern const size_t dsp_mode1_ven_TX_size;
extern const reg_config_t dsp_mode1_ven_RX[];
extern const size_t dsp_mode1_ven_RX_size;
extern const reg_config_t dsp_mode2_path_SYS[];
extern const size_t dsp_mode2_path_SYS_size;
extern const reg_config_t dsp_mode2_path_AFE[];
extern const size_t dsp_mode2_path_AFE_size;
extern const reg_config_t dsp_mode2_ven_TX[];
extern const size_t dsp_mode2_ven_TX_size;
extern const reg_config_t dsp_mode2_ven_RX[];
extern const size_t dsp_mode2_ven_RX_size;
extern const reg_config_t dsp_sleep_AFE[];
extern const size_t dsp_sleep_AFE_size;

void HAL_Delay_nMS(unsigned int t);
void BSP_Fm1505RstHigh();
void BSP_Fm1505RstLow();
void BSP_Fm1505CsLow();
void BSP_Fm1505CsHigh();
unsigned char BSP_Fm1505SpiRw(unsigned char txdata);
/**
*********************************************************************************************************
* @brief 实现毫秒级延时
* @param n_ms 需要延时的毫秒数
*********************************************************************************************************/
void dsp_delay_ms(uint32_t n_ms)
{
  ej_fm1505_phy_dly_ms(n_ms);
}
uint8_t spi_write_buffer_api(uint8_t *buffer,  uint16_t length )
{
#if 0
  uint8_t ret = 0;
  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_RESET);
  ret = HAL_SPI_Transmit(&hspi1, buffer, length, TIMEOUT_SPI_BUS);
  if(HAL_OK != ret)
    {
    HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);

    return SPI_BUS_ERR ;
    }
  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);
#endif

  ej_fm1505_phy_spi_cs_control(0);
  ej_fm1505_phy_spi_write(buffer, length);
  ej_fm1505_phy_spi_cs_control(1);

  return 0;
}
unsigned char BSP_Fm1505SpiRw(unsigned char txdata);
uint8_t spi_write_read_buffer_api(uint8_t *buffer_w, uint16_t length_w, uint8_t *buffer_r, uint16_t length_r)
{
#if 0
  uint8_t ret = 0;
  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_RESET);
  ret = HAL_SPI_Transmit(&hspi1, buffer_w, length_w, TIMEOUT_SPI_BUS);
  if(HAL_OK != ret)
    {
    HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);

    return SPI_BUS_ERR ;
    }
  ret = HAL_SPI_Receive(&hspi1, (uint8_t *)buffer_r, length_r, TIMEOUT_SPI_BUS);
  if(HAL_OK != ret)
    {
    HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);

    return SPI_BUS_ERR ;
    }
  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port, SPI1_NSS_Pin, GPIO_PIN_SET);
#endif

  ej_fm1505_phy_spi_cs_control(0);
  ej_fm1505_phy_spi_write(buffer_w, length_w);
  ej_fm1505_phy_spi_read(buffer_r, length_r);
  ej_fm1505_phy_spi_cs_control(1);

  return 0;
}
void dsp_write_reg(uint8_t addr,uint8_t value)
{
  memset(data_send1, 0, BLOCK_SEND_SIZE);
  if (addr > 0x3)
    {
    printf("dsp_write_reg addr is out of SPI Reg range [0 ~ 3]!=0x%X\n", addr);
    }
  else
    {
    data_send1[0] = SPI_REG_WR;
    data_send1[1] = addr;
    data_send1[2] = value;
    spi_write_buffer_api(data_send1, 3);
    }
}
uint8_t dsp_read_reg(uint8_t addr)
{
  uint8_t jvalue = 0;
  memset(data_send1, 0, BLOCK_SEND_SIZE);
  if (addr > 0x3)
    {
    printf("dsp_read_reg addr is out of SPI Reg range [0 ~ 3]!=0x%X\n", addr);
    }
  else
    {
    data_send1[0] = SPI_REG_RD;
    data_send1[1] = addr;
    spi_write_read_buffer_api(data_send1, 2, &jvalue, 1);
    printf("dsp_read_reg[0x%X] jvalue=0x%X\n", addr,jvalue);
    }
  return jvalue;
}
void dsp_write_reg_and_check(uint8_t addr,uint8_t value)
{
  if (addr > 0x3)
    {
    printf("dsp_write_reg_and_check addr is out of SPI Reg range [0 ~ 3]!=0x%X\n", addr);
    }
  else
    {
    dsp_write_reg(addr, value);

    uint8_t r_value = dsp_read_reg(addr);
    if (value == r_value)
      {
      printf("dsp_write_reg[0x%X] successful.\n", addr);
      }
    else
      {
      printf("dsp_write_reg[0x%X] error. w=0x%X,r=0x%X\n", addr,value,r_value);
      }
    }
}
void dsp_write_dram(uint32_t addr,uint32_t value,uint32_t length)
{
  if (addr % 2 == 1) {

      return;
  }
  if ((addr % 2 != 0) && (length == 2)) {

      return;
  }
  if ((addr % 4 != 0) && (length == 4)) {

      return;
  }
  memset(data_send1, 0, BLOCK_SEND_SIZE);
  if (2 == length)
    {
    data_send1[0] = SPI_DM_WR;
    data_send1[1] = addr & 0xFF;
    data_send1[2] = (addr >> 8) & 0xFF;
    data_send1[3] = (addr >> 16) & 0xFF;
    data_send1[4] = length/2 & 0xFF;
    data_send1[5] = 0;
    data_send1[6] = value & 0xFF;
    data_send1[7] = (value >> 8) & 0xFF;
    spi_write_buffer_api(data_send1, 8);
    }
  else if (4 == length)
    {
    data_send1[0] = SPI_DM_WR;
    data_send1[1] = addr & 0xFF;
    data_send1[2] = (addr >> 8) & 0xFF;
    data_send1[3] = (addr >> 16) & 0xFF;
    data_send1[4] = length/2 & 0xFF;
    data_send1[5] = 0;
    data_send1[6] = value & 0xFF;
    data_send1[7] = (value >> 8) & 0xFF;
    data_send1[8] = (value >> 16) & 0xFF;
    data_send1[9] = (value >> 24) & 0xFF;
    spi_write_buffer_api(data_send1, 10);
    }
  else
    {
    printf("length is err(Only 2 or 4)!=%u\n", length);
    }
}

uint8_t* dsp_read_dram(uint32_t addr,uint32_t length)
{
  if (addr % 2 == 1) {

      return NULL;
  }
  if ((addr % 2 != 0) && (length == 2)) {

      return NULL;
  }
  if ((addr % 4 != 0) && (length == 4)) {

      return NULL;
  }
  memset(data_send1, 0, BLOCK_SEND_SIZE);
  data_send1[0] = SPI_DM_RD;
  data_send1[1] = addr & 0xFF;
  data_send1[2] = (addr >> 8) & 0xFF;
  data_send1[3] = (addr >> 16) & 0xFF;
  data_send1[4] = length/2 & 0xFF;
  data_send1[5] = (length/2 >> 8) & 0xFF;
  data_send1[6] = 0;
  data_send1[7] = 0;
  spi_write_read_buffer_api(data_send1, 8, data_recv1, length);
  return data_recv1;
}

uint32_t dsp_read_dram_4B(uint32_t addr)
{
  uint8_t* pdata = dsp_read_dram(addr,4);
  if (NULL == pdata)
    {
    return 0xFFFFFFFFUL;
    }
  uint32_t jval = *pdata + *(pdata+1)*256 + *(pdata+2)*256*256 + *(pdata+3)*256*256*256;
  return jval;
}
void BSP_Fm1505RstHigh();
void BSP_Fm1505RstLow();
void codec_hw_reset(void)
{
#if 0
  //HAL_GPIO_WritePin(CODEC_RSTL_GPIO_Port, CODEC_RSTL_Pin, GPIO_PIN_RESET);
  dsp_delay_ms(100);
  //HAL_GPIO_WritePin(CODEC_RSTL_GPIO_Port, CODEC_RSTL_Pin, GPIO_PIN_SET);
  dsp_delay_ms(100);
#endif

}
void dsp_hw_reset(void)
{
  //HAL_GPIO_WritePin(DSP_RSTL_GPIO_Port, DSP_RSTL_Pin, GPIO_PIN_RESET);
  ej_fm1505_phy_chip_reset_control(TRUE);
  dsp_delay_ms(10);
  //HAL_GPIO_WritePin(DSP_RSTL_GPIO_Port, DSP_RSTL_Pin, GPIO_PIN_SET);
  ej_fm1505_phy_chip_reset_control(FALSE);
  dsp_delay_ms(10);
}
void dsp_sw_reset(void)
{

  dsp_write_reg_and_check(dsp_onoff, sw_reset_dsp);

}
void dsp_hold_dsp(void)
{

  dsp_write_reg_and_check(dsp_onoff, hold_dsp);

}

/**
*********************************************************************************************************
* @brief Starts DSP operation
* @note Writes run command (0x04) to dsp_onoff register to activate DSP
*       Should be called after firmware download and configuration
* @param None
* @retval None
*********************************************************************************************************
*/
void dsp_run_dsp(void)
{
  dsp_write_reg_and_check(dsp_onoff, run_dsp);
}

/**
*********************************************************************************************************
* @brief Sets DSP operation mode (Pending implementation)
* @note Reserved interface for future operation mode switching
* @param mode - Target operation mode identifier
*       Mode definitions to be implemented according to system requirements
* @retval None
*********************************************************************************************************
*/
bool dsp_switch_mode_set(void)
{
  bool ret = false;
  uint32_t addr = dsp_addr.afe_param_base + COMM_SCENE_FLAG;


  dsp_write_dram(addr, 1, 4);
  for (int jaa = 0; jaa < 5; ++jaa)
    {
    dsp_delay_ms(100);
    uint32_t dsp_msg_ack = dsp_read_dram_4B(addr);
    if (dsp_msg_ack == 0)
      {
        ret = true;
        break;
      }
    }

  return ret;
}


bool dsp_get_base_addr(void)
{


  dsp_addr.ven_param_base = dsp_read_dram_4B(FM_ALG_PARAM_BASE_ADDR);
  dsp_addr.ven_param_base &= 0xFFFFFFFC;


  dsp_addr.debug_param_base = dsp_read_dram_4B(SYS_DBG_BASE_ADDR);
  dsp_addr.debug_param_base &= 0xFFFFFFFC;


  dsp_addr.afe_param_base = dsp_read_dram_4B(AFE_CNF_BASE_ADDR);
  dsp_addr.afe_param_base &= 0xFFFFFFFC;


  dsp_addr.sys_param_base = dsp_read_dram_4B(SYS_CNF_BASE_ADDR);
  dsp_addr.sys_param_base &= 0xFFFFFFFC;
  uint32_t base_tmp1 = FM_ALG_VER_BASE_ADDR;








  dsp_SW_BASE sw_base;
  base_tmp1 = dsp_addr.ven_param_base;
  sw_base.auto_ven_base = dsp_read_dram_4B(base_tmp1 + FM_AUTO_VEN_PARAM_BASE);
  sw_base.auto_rcv_fliter_base = dsp_read_dram_4B(base_tmp1 + FM_AUTO_RCV_FILTER_BASE);
  sw_base.aoaa_ven_base = dsp_read_dram_4B(base_tmp1 + FM_AOAA_VEN_PARAM_BASE);
  sw_base.aoaa_isd_base = dsp_read_dram_4B(base_tmp1 + FM_AOAA_ISD_PARAM_BASE);


  uint32_t offset = 0;
  if (sw_base.auto_ven_base != 0x55665566UL) {
      offset = FM_AUTO_VEN_PARAM_BASE;
      printf("[INFO] Algorithm : FM_AUTO_VEN_PARAM_BASE\n");
  } else if (sw_base.aoaa_ven_base != 0x55665566UL) {
      offset = FM_AOAA_VEN_PARAM_BASE;
      printf("[INFO] Algorithm : FM_AOAA_VEN_PARAM_BASE\n");
  } else {
      printf("[ERROR] Can't get valid ven base address from VOS!\n");
      return false;
}
  dsp_addr.ven_param_base = dsp_read_dram_4B(dsp_addr.ven_param_base + offset);

  printf("ven_param_base = 0x%08X\n", dsp_addr.ven_param_base);
  printf("debug_param_base = 0x%08X\n", dsp_addr.debug_param_base);
  printf("afe_param_base = 0x%08X\n", dsp_addr.afe_param_base);
  printf("sys_param_base = 0x%08X\n", dsp_addr.sys_param_base);


  return true;
}

/**
*********************************************************************************************************
* @brief Checks DSP operational status
* @note Current implementation is a stub that always returns true
*       Should be replaced with actual status register checks in production code
* @param None
* @retval true - DSP is in running state (default)
*        false - DSP is not functioning properly
*********************************************************************************************************
*/
bool dsp_check_run(void)
{
  uint32_t counter_addr = dsp_addr.debug_param_base + SYS_DBG_STA;
  uint32_t counter[3];
  bool state = false;




#if 1

  uint8_t r_value = dsp_read_reg(dsp_onoff);
  if (run_dsp != r_value)
    {
    printf("dsp DSP is not running! (DSP ON/OFF REG != 0x04)\n");
    }
  else
    {
    dsp_get_base_addr();
    for (int jaa = 0; jaa < 3; ++jaa)
      {
      counter[jaa] = dsp_read_dram_4B(counter_addr);

      dsp_delay_ms(100);
      }


    printf("counter=[%u -> %u -> %u]\n", counter[0],counter[1],counter[2]);

    if (counter[0] < counter[1] || counter[1] < counter[2])
      {
      state = true;
      }
    else
      {
      state = false;
      }
    }
#endif




  dsp_fw_version();
  printf("<<5 conter=%d\n>>",dsp_read_dram_4B(counter_addr));
	printf("<<6 conter=%d\n>>",dsp_read_dram_4B(counter_addr));

  dsp_sw_version();
  printf("<<7 conter=%d\n>>",dsp_read_dram_4B(counter_addr));
  printf("<<8 conter=%d\n>>",dsp_read_dram_4B(counter_addr));


   counter_addr = dsp_addr.afe_param_base + 0x90;


   printf("<<88888 conter=%d\n>>",dsp_read_dram_4B(counter_addr));


  return state;
}


/**
*********************************************************************************************************
* @brief DSP芯片初始化和启动
* @retval bool - 初始化结果
*         @arg true  : DSP初始化成功并正常运行
*         @arg false : DSP初始化失败或未响应
*********************************************************************************************************/
bool dsp_init(void)
{
  dsp_hw_reset();

  dsp_sw_reset();

  dsp_hold_dsp();
  dsp_download_bins();
  dsp_delay_ms(100);
  dsp_get_base_addr();
  dsp_fw_version();
  dsp_sw_version();

  dsp_get_base_addr();
  dsp_write_mode_param(DSP_PARAM_SYS,dsp_mode1_path_SYS,dsp_mode1_path_SYS_size);



  dsp_write_mode_param(DSP_PARAM_AFE,dsp_mode1_path_AFE,dsp_mode1_path_AFE_size);
  dsp_get_base_addr();
  dsp_write_mode_param(DSP_PARAM_TX,dsp_mode1_ven_TX,dsp_mode1_ven_TX_size);
  dsp_write_mode_param(DSP_PARAM_RX,dsp_mode1_ven_RX,dsp_mode1_ven_RX_size);
  dsp_get_base_addr();

  dsp_run_dsp();
  dsp_delay_ms(100);


  if(dsp_check_run())
    {
    printf("Download code and vec successfully! DSP is running!\n");
    return true;
    }
  else
    {
    printf("Download code and vec failed! DSP is stopped!\n");
    return false;
    }
}
void dsp_fw_version(void)
{
  uint32_t jver = dsp_read_dram_4B(DSP_FW_VER_ADDR);
  printf("FW Version = 0x%08X\n", jver);
}
void dsp_sw_version(void)
{
  uint32_t jaddr = dsp_read_dram_4B(FM_ALG_VER_BASE_ADDR);
  jaddr &= 0xFFFFFFFC;
  for (int jaa = 0; jaa < 5; ++jaa)
    {
    uint32_t jver = dsp_read_dram_4B(jaddr + jaa*4);
    printf("VER[%u] = 0x%08X\n", jaa,jver);
    }
}
void Reverse_Endian(unsigned char *pdata, unsigned char size)
{
    unsigned char i;
    unsigned char temp;
    for (i = 0; i < size >> 1; i++)
    {
        temp = *(pdata + i);
        *(pdata + i) = *(pdata + size - 1 - i);
        *(pdata + size - 1 - i) = temp;
    }
}
void dsp_send_bin_data(const uint8_t *pData)
{
  uint32_t total_size = 0;
  uint32_t processed = 0;
  uint32_t blocks = 0;
  uint32_t addr = 0;
  memset(data_send1, 0, BLOCK_SEND_SIZE);
  if (IRAM0_DATA_ARRAY == pData)
    {

    total_size = sizeof(IRAM0_DATA_ARRAY);
    printf("IRAM_total_size=%u\n", total_size);
    addr = IRAM_START_ADDR;
    data_send1[0] = SPI_IM_WR;
    }
  else if (DRAM0_DATA_ARRAY == pData)
    {

    total_size = sizeof(DRAM0_DATA_ARRAY);
    printf("DRAM_total_size=%u\n", total_size);
    addr = DRAM_START_ADDR;
    data_send1[0] = SPI_DM_WR;
    }
  else
    {
    printf("code_type is err!=0x%08X\n", (uint32_t)pData);
    }
  blocks = total_size / BLOCK_DATA_SIZE;
  while(blocks--)
    {
    memset(&data_send1[1], 0, BLOCK_SEND_SIZE-1);
    memcpy(data_send1+BLOCK_HEADER_SIZE, pData + processed, BLOCK_DATA_SIZE);
    for(int i=0; i<BLOCK_DATA_SIZE; i+=8)
      {
      Reverse_Endian(&data_send1[i+BLOCK_HEADER_SIZE],8);
      }
//    data_send1[0] = SPI_IM_WR;
    data_send1[1] = addr & 0xFF;
    data_send1[2] = (addr >> 8) & 0xFF;
    data_send1[3] = (addr >> 16) & 0xFF;
    data_send1[4] = BLOCK_DATA_SIZE/2 & 0xFF;
    data_send1[5] = (BLOCK_DATA_SIZE/2 >> 8) & 0xFF;
    spi_write_buffer_api(data_send1, BLOCK_SEND_SIZE);
    processed += BLOCK_DATA_SIZE;
    addr += BLOCK_DATA_SIZE;
    }

}

/**
*********************************************************************************************************
* @brief Downloads firmware images to DSP target memories
* @note This function performs two critical operations:
*       1. Sends IRAM image to instruction memory
*       2. Sends DRAM image to data memory
* @param None
* @retval None
*********************************************************************************************************
*/
void dsp_download_bins(void)
{
  dsp_send_bin_data(DRAM0_DATA_ARRAY);
  dsp_send_bin_data(IRAM0_DATA_ARRAY);
}

void dsp_write_mode_param(en_param_type param_type, const reg_config_t register_config[],
                                          const size_t register_config_size)
{
  uint32_t base_addr = 0;
  uint32_t para_val_len = 4;
  uint32_t para_addr_step = 1;

  switch (param_type)
    {
    case DSP_PARAM_TX:
      para_val_len = 2;
      para_addr_step = DSP_VEC_STEP_2B;
      base_addr = dsp_addr.ven_param_base;

      break;
    case DSP_PARAM_RX:
      para_val_len = 2;
      para_addr_step = DSP_VEC_STEP_2B;
      base_addr = dsp_addr.ven_param_base+VEN_INDEX_RX*DSP_VEC_STEP_2B;

      break;
    case DSP_PARAM_DEBUG:
      para_val_len = 2;
      para_addr_step = DSP_VEC_STEP_2B;
      base_addr = dsp_addr.ven_param_base+VEN_INDEX_DEBUG*DSP_VEC_STEP_2B;

      break;
    case DSP_PARAM_HW:
      para_val_len = 4;
      para_addr_step = 1;
      base_addr = 0;

      break;
    case DSP_PARAM_AFE:
      para_val_len = 4;
      para_addr_step = 1;
      base_addr = dsp_addr.afe_param_base;

      break;
    case DSP_PARAM_SYS:
      para_val_len = 4;
      para_addr_step = 1;
      base_addr = dsp_addr.sys_param_base;

      break;
    default:
     para_val_len = 4;
     para_addr_step = 1;
     base_addr = 0;

     break;
     }

  for (int jaa = 0; jaa < register_config_size; ++jaa)
    {
//
    dsp_write_dram(base_addr + register_config[jaa].addr*para_addr_step, register_config[jaa].value, para_val_len);

    }
}
void dsp_load_sleep_vec(void)
{
  dsp_get_base_addr();
  dsp_write_mode_param(DSP_PARAM_AFE,dsp_sleep_AFE,dsp_sleep_AFE_size);
}

/**
*********************************************************************************************************
* @brief 切换DSP芯片工作模式
* @param mode 目标工作模式，支持以下模式：
*        - mode_16k_LIN_SRCon
*        - mode_8k_LIN_SRCon
* @retval bool - 切换DSP芯片工作模式结果
*         @arg true  : 切换成功
*         @arg false : 切换失败
*********************************************************************************************************/
bool dsp_switch_mode(en_chip_mode mode)
{
  bool ret = false;
  dsp_get_base_addr();
  dsp_load_sleep_vec();
  if (dsp_switch_mode_set())
	{
	printf("dsp_switch_mode_set pass.\n");
	}
  else
	{
	printf("dsp_switch_mode_set fail.\n");
	}
  if (dsp_mode1 == mode)
	{
	dsp_get_base_addr();
	dsp_write_mode_param(DSP_PARAM_SYS,dsp_mode1_path_SYS,dsp_mode1_path_SYS_size);
	dsp_write_mode_param(DSP_PARAM_AFE,dsp_mode1_path_AFE,dsp_mode1_path_AFE_size);
	dsp_get_base_addr();
	dsp_write_mode_param(DSP_PARAM_TX,dsp_mode1_ven_TX,dsp_mode1_ven_TX_size);
	dsp_write_mode_param(DSP_PARAM_RX,dsp_mode1_ven_RX,dsp_mode1_ven_RX_size);
	}
  else if (dsp_mode2 == mode)
	{
	dsp_get_base_addr();
	dsp_write_mode_param(DSP_PARAM_SYS,dsp_mode2_path_SYS,dsp_mode2_path_SYS_size);
	dsp_write_mode_param(DSP_PARAM_AFE,dsp_mode2_path_AFE,dsp_mode2_path_AFE_size);
	dsp_get_base_addr();
	dsp_write_mode_param(DSP_PARAM_TX,dsp_mode2_ven_TX,dsp_mode2_ven_TX_size);
	dsp_write_mode_param(DSP_PARAM_RX,dsp_mode2_ven_RX,dsp_mode2_ven_RX_size);
	}
  else
	{
	printf("This mode is not supported.%u\n",mode);
	}
  //dsp_delay_ms(500);
  //dsp_write_reg(dsp_addr.afe_param_base + 0x0000028C, 0x00000001);
  //dsp_write_dram(dsp_addr.afe_param_base + 0x0000028C, 0x00000001, 4);
  dsp_switch_mode_set();
  //dsp_delay_ms(500);

  ret = dsp_check_run();
  if(ret)
	{
	printf("Mode switched successfully! DSP is running!\n");
	}
  else
	{
	printf("Mode switched failed! DSP is stopped!\n");
	}

	printf("<<reg =%x\n>>",dsp_read_dram_4B(dsp_addr.afe_param_base + 0x0000028C));
    printf("<<reg =%x\n>>",dsp_read_dram_4B(dsp_addr.afe_param_base + 0x00000080));
    printf("<<reg =%x\n>>",dsp_read_dram_4B(dsp_addr.afe_param_base + 0x00000084));
  return ret;
}
#endif
